package org.swizframework.util {
	
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	import mx.managers.CursorManager;
	import mx.rpc.AsyncToken;
	import mx.rpc.IResponder;
	import mx.rpc.events.ResultEvent;
	
	/**
	 *
	 * @author soenkerohde
	 *
	 */
	public class TestUtil {
		/**
		 * addAsync can be used from TestCases which want to rest an
		 * asynchronous action (service call which returns AsyncToken)
		 *
		 * Usage from TestCase:
		 *
		 * function testLogin():void
		 * {
		 * 		TestUtil.addAsync(this, userDelegate.loginUser("foo", "bar"), onLogin, 5000);
		 * }
		 *
		 * @param tc The TestCase itself from which this is called
		 * @param token The AsyncToken returned by the service-/delegate-call
		 * @param callback function to call in the testcase when operation is complete
		 * @param delay time to wait until the call is considered a failure
		 *
		 */
		public static function addAsync( testCase : Object, token : AsyncToken, callback : Function, delay : Number ) : void {
			var responder:TestResponder = new TestResponder();
			token.addResponder( responder );
			// this has changed from addAsync, because I am now using fluint
			responder.addEventListener( ResultEvent.RESULT, testCase.asyncHandler( callback, delay ) );
		}
		
		/**
		 * mockResult can be used from mocked delegate
		 * a delegate method call generally returns an async token
		 * which is the result of a service call.
		 *
		 * Usage from mocked Delegate:
		 *
		 * function loginUser(username:String, password:String):AsyncToken
		 * {
		 * 		return TestUtil.mockResult(<user username="testUser" />, 1000);
		 * }
		 *
		 * @param result
		 * @param delay
		 * @param showBusyCursor
		 * @return
		 *
		 */
		public static function mockResult( result : Object, delay : Number = 500, showBusyCursor : Boolean = true ) : AsyncToken {
			return mockResultEvent( new ResultEvent( ResultEvent.RESULT, false, true, result ), delay, showBusyCursor );
		}
		
		/**
		 * @param resultEvent ResultEvent for IResponder
		 * @param delay in ms
		 * @param showBusyCursor to indicate pending with BusyCursor
		 * @return AsyncToken
		 *
		 */
		public static function mockResultEvent( resultEvent : ResultEvent, delay : Number = 500, showBusyCursor : Boolean = true ) : AsyncToken {
			if ( showBusyCursor ) {
				CursorManager.setBusyCursor();
			}
			var token:AsyncToken = new AsyncToken( null );
			var t:Timer = new Timer( delay, 1 );
			t.addEventListener( TimerEvent.TIMER_COMPLETE, function( event : TimerEvent ) : void
				{
					for each ( var responder : IResponder in token.responders )
					{
						responder.result( resultEvent );
					}
					t = null;
					token = null;
					if ( showBusyCursor )
					{
						CursorManager.removeBusyCursor();
					}
				} );
			t.start();
			return token;
		}
	}
}